package jssia.config.yaml;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.Set;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

public class ConfigurationFactory {

    private static Set<DatabaseConfiguration> databaseConfigs;
    public static DatabaseConfiguration[] getDatabaseConfigs() {
        if (databaseConfigs == null)
            databaseConfigs = getConfigs(DatabaseConfiguration.class, YamlLoaders.DATABASE);

        DatabaseConfiguration[] dbConfigs = new DatabaseConfiguration[databaseConfigs.size()];
        int i = 0;
        for (DatabaseConfiguration dbConfig : databaseConfigs) {
            dbConfigs[i] = new DatabaseConfiguration(dbConfig);
            i++;
        }
        return dbConfigs;
    }

    private static JssiaConfiguration jssiaConfig;
    public static JssiaConfiguration getJssiaConfiguration() {
        if (jssiaConfig == null)
            jssiaConfig = getConfig(JssiaConfiguration.class, YamlLoaders.JSSIA);
        return new JssiaConfiguration(jssiaConfig);
    }

    private static <T> T getConfig(Class<T> clas, YamlLoaders yamlLoader) {
        final Yaml dbYaml = new Yaml(new Constructor(clas));
        InputStream is = yamlLoader.getFileInputStream();
        try {
            return (T) dbYaml.load(is);
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static <T> Set getConfigs(Class<T> clas, YamlLoaders yamlLoader) {
        final Yaml dbYaml = new Yaml(new Constructor(clas));
        final Set configs = new HashSet();
        InputStream is = yamlLoader.getFileInputStream();
        try {
            for (Object object : dbYaml.loadAll(is)) {
                final T config = (T) object;
                if (configs.contains(config))
                    throw new IllegalStateException(yamlLoader.getFilePath()
                            + " contains duplicate configurations for  \'"
                            + config + "\'.");

                configs.add(config);
            }
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return configs;
    }
}
